package hello

import "fmt"

/*
闭包:
  匿名函数是一个"内联"语句或表达式。匿名函数的优越性在于可以直接使用函数内的变量，不必申明。
  以下实例中，我们创建了函数 getSequence() ，返回另外一个函数。该函数的目的是在闭包中递增 i 变量，代码如下：
*/

func ClosureTest3() {
	fmt.Println("------------ Closure Test3() --------------")
	add_func := add(1, 2)
	fmt.Println("add_func() -------------")
	fmt.Println(add_func())
	fmt.Println(add_func())
	fmt.Println(add_func())

	add2_func := add2(1, 2)
	fmt.Println("add2_func() -------------")
	fmt.Println(add2_func(1, 1))
	fmt.Println(add2_func(0, 0))
	fmt.Println(add2_func(2, 2))

	// -----------------------------------------------
	/* nextNumber 为一个函数，函数 i 为 0 */
	nextNumber := getSequence()

	/* 调用 nextNumber 函数，i 变量自增 1 并返回 */
	fmt.Println("getSequence() -------------")
	fmt.Println(nextNumber())
	fmt.Println(nextNumber())
	fmt.Println(nextNumber())

	/* 创建新的函数 nextNumber1，并查看结果 */
	nextNumber1 := getSequence()
	fmt.Println(nextNumber1())
	fmt.Println(nextNumber1())

}

// 闭包使用方法
func add(x1, x2 int) func() (int, int) {
	i := 0
	return func() (int, int) {
		i++
		return i, x1 + x2
	}
}

func getSequence() func() int {
	i := 0
	return func() int {
		i += 1
		return i
	}
}

// 闭包使用方法
func add2(x1, x2 int) func(x3 int, x4 int) (int, int, int) {
	i := 0
	return func(x3 int, x4 int) (int, int, int) {
		i++
		return i, x1 + x2, x3 + x4
	}
}
